package wangjg.commons.bean;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.ehcache.hibernate.management.impl.BeanUtils;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;

/**
 * 根据属性的拼音排序
 * @author wangjg
 *
 */
@SuppressWarnings({"rawtypes"})
public class BeanComparatorByPinyin implements Comparator{
	private String orderBy;
	private int asc = 1;
	private Map<String,String> pinyinMap = new HashMap<String,String>();
	
	public BeanComparatorByPinyin(String orderBy, boolean asc) {
		this.orderBy = orderBy;
		this.asc = asc?1:-1;
	}

	public int compare(Object bean1, Object bean2) {
		try {
			Object pv1 = BeanUtil.getProperty(bean1, orderBy);
			Object pv2 = BeanUtil.getProperty(bean2, orderBy);
			String pv1py = this.getPinyinKey(""+pv1);
			String pv2py = this.getPinyinKey(""+pv2);
			
			return this.asc * pv1py.compareTo(pv2py);
			
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	private String getPinyinKey(String str) throws Exception {
		String pinyin = this.pinyinMap.get(str);
		if(pinyin==null){
			pinyin = toPinyinKey(str);
			this.pinyinMap.put(str, pinyin);
		}
		
		return pinyin;
	}
	
	private static HanyuPinyinOutputFormat fmt = new HanyuPinyinOutputFormat();
	
	static{
		fmt.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
	}
	
	private static String toPinyinKey(String str){
		if(str==null||str.length()==0){
			return "";
		}
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < str.length(); i++) {
			char ch = str.charAt(i);
			String[] ss;
			try {
				ss = PinyinHelper.toHanyuPinyinStringArray(ch, fmt);
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
			if(ss!=null && ss.length>0){
				sb.append(ss[0]);
			}else{
				sb.append('\0');//非中文视为比中文小
				sb.append(ch);
			}
		}
		return sb.toString();
	}
	
	@SuppressWarnings("unchecked")
	static <T> List<T> sortList(List<T> list, String orderBy){
		if(list.isEmpty()){
			return list;
		}
		Object tmp = BeanUtils.getBeanProperty(list.get(0), orderBy);
		if(!(tmp instanceof String)){
			Collections.sort(list, new BeanComparator1(orderBy, true));
			return list;
		}
		List<String> list1 = new ArrayList<String>();
		List<String> list2 = new ArrayList<String>();
		Map<String,T> map = new HashMap<String,T>();
		for(int i=0;i<list.size();i++){
			T bean = list.get(i);
			String key = (String) BeanUtils.getBeanProperty(bean, orderBy);
			String py = BeanComparatorByPinyin.toPinyinKey(key);
			String pykey = py+'-'+i;
			if(key.length()==0 || py.length()==0 || py.charAt(0)==key.charAt(0)){
				list1.add(pykey);
			}else{
				list2.add(pykey);
			}
			map.put(pykey, bean);
		}
		
		Collections.sort(list1);
		Collections.sort(list2);
		
		List<T> sortedList = new ArrayList<T>();
		for(String py:list1){
			sortedList.add((T) map.get(py));
		}
		for(String py:list2){
			sortedList.add((T) map.get(py));
		}
		return sortedList;
	}
	
	public static void main(String args[]) throws Exception{
		System.out.println(BeanComparatorByPinyin.toPinyinKey("abc你好"));
	}
}
